<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>vue监测数据改变的原理-数组</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">

        <button @click="students.age++">点击学生年龄加1</button><br>
        <button @click="addsex">点击添加学生性别信息</button><br>
        <button @click="addperson">在列表开始添加一个朋友</button><br>
        <button @click="updatename">修改第一个朋友名字为：张三</button><br>
        <button @click="addhobby">添加一个爱好</button><br>
        <button @click="updatehobby">修改第一个爱好为开车</button><br>
        <button @click="removesmoke">过滤掉爱好中的抽烟</button><br>


        <hr>
        <h2>学生姓名:{{students.name}}</h2>
        <h2>学生年龄:{{students.age}}</h2>
        <h2 v-if="students.sex">学生性别:{{students.sex}}</h2>
        <h2>朋友们</h2>
        <ul>
            <li v-for="(f,index) in students.friends" :key="index">
                {{f.name}}--{{f.age}}
            </li>
        </ul>
        <hr>
        <h2>学生兴趣</h2>
        <ul>
            <li v-for="(h,index) in students.hobby" :key="index">
                {{h}}
            </li>
        </ul>
    </div>
    <script>

        /* vue监视数据的原理:
        1.vue会监视data中所有层次的数据

        2.如何监测对象中的数据？
        通过setter监视数据，且要在new vue时就传入要监测的数据
            (1)对象中后追加的数据，vue默认不做响应式处理
            (2)如需给后增加的数据做响应式 需使用如下API
        Vue.set(target, propertyName / index, value)或
        vm.$set(target, propertyName / index, value)

        3.如何监测数组中的数据？
        通过包裹数组更新元素的方法实现，本质就是做了两件事：
        (1)调用原生对应的方法对数组进行更新
        (2)重新解析模板进而更新页面

        4.在vue中修改数组中的某个元素一定要用如下方法
        push() pop() shift() unshift() sort() reverse() splice()
        Vue.set()   vm.$set()

        特别注意：Vue.set() vm.$set()不能给vm或vm的 根 数据对象添加属性
 */


        // 把data获取到并变化为_data称为数据劫持
        Vue.config.productionTip = false
        var vm = new Vue({
            el: '#root',
            data: {
                students: {
                    name: 'tom',
                    age: 18,
                    friends: [
                        { name: 'jerry', age: 35 },
                        { name: 'tony', age: 36 },
                    ],
                    hobby: ['抽烟', '喝酒', '烫头']
                }
            },
            methods: {
                addsex() {
                    // Vue.set(this.students, 'sex', '男')
                    this.$set(this.students, 'sex', '男')
                },
                addperson() {
                    this.students.friends.unshift({ name: 'jack', age: 70 });
                },
                updatename() {
                    this.students.friends[0].name = '张三';
                },
                addhobby() {
                    this.students.hobby.push('学习');
                },
                updatehobby() {
                    // this.students.hobby.splice(0, 1, '开车');
                    // Vue.set(this.students.hobby, 0, '开车');
                    this.$set(this.students.hobby, 0, '开车');
                },
                removesmoke() {
                    this.students.hobby = this.students.hobby.filter((h) => {
                        return h !== '抽烟'
                    })
                }
            }
        });
    </script>
</body>

</html>